package com.tom.sen.config;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import com.tom.sen.annotation.SensitiveInfo;
import com.tom.sen.base.SensitiveDataConverter;
import com.tom.sen.base.SensitiveType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StopWatch;

import java.lang.reflect.Field;
import java.util.*;


/**
 *
 * 基于gitee 源码
 * https://gitee.com/guofb/log-shield-spring-boot-starter
 *  https://gitee.com/JustryDeng/logback-defender
 *
 * @author : fengbo.guo
 * @date : 2022-03-18 17:14
 * @Description : 脱敏配置自动注入
 */
@Configuration
@EnableConfigurationProperties({LogShieldProperties.class})
@Slf4j
public class LogShieldAutoConfiguration implements SmartInitializingSingleton {


    @Autowired
    private LogShieldProperties logShieldProperties;



    /**
     * 开关
     */
    private boolean enable;

    /**
     * 需要脱敏的包集合 多个以 【,】 隔开
     */
    private String includePackages;


    @Override
    public void afterSingletonsInstantiated() {
        //配置脱敏包

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        enable=logShieldProperties.isEnable();
        includePackages=logShieldProperties.getIncludePackages();

        if(logShieldProperties.isEnable()){
            scanLogShieldPages( logShieldProperties.getIncludePackages());

        }

        //注入开关
        SensitiveDataConverter.setEnable(logShieldProperties.isEnable());

        stopWatch.stop();
        log.info("LogShield init ,costTime:{}",stopWatch.getTotalTimeSeconds());

    }





    public void scanLogShieldPages(String includePackages){
        log.info("logShieldProperties:{}",includePackages);
        Map<String,SensitiveType> keyMap=new HashMap();
        if (StringUtils.isNotBlank(includePackages)) {
            String[] split = includePackages.split(",");
            for (int m = 0,n=split.length; m < n; m++) {
                String packAge = split[m];
                if(StringUtils.isNotBlank(packAge)){
                    Set<Class<?>> classes = ClassUtil.scanPackage(packAge);

                    classes.forEach(clazz->
                    {
                        Field[] declaredFields = clazz.getDeclaredFields();
                        if(ArrayUtil.isNotEmpty(declaredFields)){

                            for (int i = 0,j=declaredFields.length; i <j; i++) {
                                Field field = declaredFields[i];
                                SensitiveInfo annotation = field.getAnnotation(SensitiveInfo.class);
                                if(annotation!=null){
                                    keyMap.put(field.getName(),annotation.type());
                                }
                            }
                        }

                    });
                }


            }
            SensitiveDataConverter.addIncludePackages(Arrays.asList(split));

        }
        log.info("keys:{}",keyMap.keySet());
        SensitiveDataConverter.addkeys(keyMap);
    }

    /**
     * 时区配置
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
    {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
    }
}

